import { shouldUpdateDependencies } from '@/utils/antd';
import { Button, Form, Input, Space, notification, Drawer, Switch } from 'antd';
import TextArea from 'antd/lib/input/TextArea';
import ReactMarkdown from 'react-markdown';
import StyleModule from './style.module.less';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dark } from 'react-syntax-highlighter/dist/esm/styles/prism';
import remarkGfm from 'remark-gfm';
import { useModel, history, useLocation } from '@umijs/max';
import { IMAGE_FALL_BACK } from '@/constant';
import { useEffect, useMemo, useState } from 'react';
import { DEFAULT_REQUIRED_RULE } from '@/constant';
import SingleUpload from '@/components/SingleUpload';
import DebounceSelect from '@/components/DebounceSelect';
import {
  useTagFetchOptions,
  useUserFetchOptions,
} from '@/hooks/business/useFetchOptions';
import { addArticle, getArticle, updateArticle } from '@/services/article';
import { ResponseCode } from '@/utils/request';
import { ArticleStatusType } from '@/DatabaseType/Article';
import { PageHeader } from '@ant-design/pro-components';

const MarkdownEditor = () => {
  const [formInstance] = Form.useForm();
  const { initialState } = useModel('@@initialState');
  const [open, setOpen] = useState(false);

  const search = useLocation().search;
  const articleId = useMemo(() => {
    const id = new URLSearchParams(search).get('id');
    return id !== null ? Number(id) : null;
  }, [search]);

  // 一键填充摘要
  function fillOutline() {
    const { content } = formInstance.getFieldsValue();
    if (content) {
      formInstance.setFieldValue('outline', content.slice(0, 127));
      Promise.resolve().then(() => {
        formInstance.validateFields(['outline']);
      });
    }
  }

  // 获取标签列表
  const fetchTagList = useTagFetchOptions();

  const fetchUserList = useUserFetchOptions();

  // 是否为更新，请求更新信息
  useEffect(() => {
    if (articleId) {
      getArticle(articleId)
        .then((res) => {
          const { code, data, message: msg } = res;
          if (code === ResponseCode.Success) {
            formInstance.setFieldsValue({
              headline: data.headline,
              outline: data.outline,
              content: data.content,
              userId: data.userId,
              tagIds: data.tagIds,
              coverUrl: data.coverUrl,
              status: data.status,
            });
            return;
          }
          notification.error({ message: msg || '文章详情获取失败' });
        })
        .catch((error) => {
          notification.error({ message: error.message || '文章详情获取失败' });
        });
    }
  }, [articleId, formInstance]);

  // 确认发布
  async function onSure() {
    let formDate;
    try {
      formDate = await formInstance.validateFields();
    } catch (error: any) {
      const message = error?.errorFields?.[0]?.errors?.[0];
      notification.warning({ message });
      return;
    }
    formDate.status = formDate.status
      ? ArticleStatusType.Draft
      : ArticleStatusType.Finalize;
    if (articleId === null) {
      try {
        const {
          data: newRecordId,
          code,
          message: msg,
        } = await addArticle(formDate);
        if (code === ResponseCode.Success) {
          notification.success({
            message: `新增ID: ${newRecordId}成功`,
          });
          setOpen(false);
        } else {
          notification.error({ message: msg || '新增失败' });
        }
      } catch (error: any) {
        notification.error({ message: error?.message || '新增失败' });
      }
    } else {
      try {
        const { code, message: msg } = await updateArticle(articleId, formDate);
        if (code === ResponseCode.Success) {
          notification.success({
            message: `更新成功`,
          });
          setOpen(false);
        } else {
          notification.error({ message: msg || '更新失败' });
        }
      } catch (error: any) {
        notification.error({ message: error?.message || '更新失败' });
      }
    }
  }

  return (
    <Form
      className={StyleModule['markdown-editor']}
      form={formInstance}
      labelCol={{ span: 3 }}
    >
      <PageHeader
        avatar={{
          src: initialState?.currentUser?.avatarImage || IMAGE_FALL_BACK,
          onClick: () => [history.back()],
        }}
        title="MD"
        subTitle="创作属于你的文章"
        extra={
          <Space>
            <Button
              type="primary"
              onClick={() => {
                const { headline, content } = formInstance.getFieldsValue();
                if (!headline) {
                  notification.warning({ message: '请填写文章标题' });
                  return;
                }
                if (!content) {
                  notification.warning({ message: '请填写文章内容' });
                  return;
                }
                setOpen(true);
              }}
            >
              发布
            </Button>
          </Space>
        }
        tags={
          <Form.Item name="headline" noStyle>
            <Input placeholder="文章标题..." className="title" autoFocus />
          </Form.Item>
        }
        ghost={false}
      />
      <div className="editor-container">
        <div className="editor">
          <Form.Item name="content" noStyle>
            <TextArea style={{ height: '100%' }} placeholder="文章内容..." />
          </Form.Item>
        </div>
        <div className="preview">
          <Form.Item
            noStyle
            shouldUpdate={shouldUpdateDependencies(['content'])}
          >
            {({ getFieldValue }) => {
              const content = getFieldValue('content') || '';
              return (
                <ReactMarkdown
                  // 代码高亮
                  components={{
                    code({ node, inline, className, children, ...props }) {
                      const match = /language-(\w+)/.exec(className || '');
                      return !inline && match ? (
                        <SyntaxHighlighter
                          {...props}
                          style={dark}
                          language={match[1]}
                          PreTag="div"
                        >
                          {String(children).replace(/\n$/, '')}
                        </SyntaxHighlighter>
                      ) : (
                        <code className={className} {...props}>
                          {children}
                        </code>
                      );
                    },
                  }}
                  remarkPlugins={[remarkGfm]}
                >
                  {content}
                </ReactMarkdown>
              );
            }}
          </Form.Item>
        </div>
      </div>
      <Drawer
        title="发布文章"
        open={open}
        onClose={() => setOpen(false)}
        width={736}
        footer={
          <Space>
            <Button onClick={() => setOpen(false)}>取消</Button>
            <Button type="primary" onClick={onSure}>
              发布
            </Button>
          </Space>
        }
        footerStyle={{ display: 'flex', flexDirection: 'row-reverse' }}
      >
        <Form.Item
          label="作者"
          name="userId"
          required
          rules={DEFAULT_REQUIRED_RULE}
        >
          <DebounceSelect fetchOptions={fetchUserList} showArrow={false} />
        </Form.Item>
        <Form.Item
          label="添加标签"
          name="tagIds"
          required
          rules={DEFAULT_REQUIRED_RULE}
        >
          <DebounceSelect
            mode="multiple"
            fetchOptions={fetchTagList}
            showArrow={false}
            // 确保最多只能选择两个
            onChange={(value: number[] | undefined) => {
              if (value && value.length >= 3) {
                formInstance.setFieldValue(
                  'tagIds',
                  value.slice(value.length - 2),
                );
              }
            }}
          />
        </Form.Item>
        <Form.Item
          label="文章封面"
          required
          rules={DEFAULT_REQUIRED_RULE}
          extra={'建议尺寸：2:1'}
          name="coverUrl"
        >
          <SingleUpload uploadBoxStyle={{ width: 320, height: 160 }} />
        </Form.Item>
        <Form.Item
          label="文章摘要"
          required
          rules={DEFAULT_REQUIRED_RULE}
          extra={<a onClick={fillOutline}>一键填充</a>}
          name="outline"
        >
          <TextArea autoSize={{ minRows: 6 }} maxLength={127} />
        </Form.Item>
        <Form.Item label="草稿" valuePropName="checked" required name="status">
          <Switch />
        </Form.Item>
      </Drawer>
    </Form>
  );
};

export default MarkdownEditor;
